
/*
 * Krótki opis klasu umieść tu.
 * Tu i tu i tu.
 */
package steg.steki.bmp;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Random;
import steg.steki.PlikSteg;
import steg.steki.StegException;
import steg.sekret.Sekret;
import steg.sekret.SekretInfo;
import steg.sekret.UnSekret;
import steg.utils.MojaLinkedHashMap;

/**
 * Klasa reprezentująca BMP.
 *
 * @author 
 */
public class PlikBMP extends PlikSteg {

// ------------------------------- ZIENNE PRYWATNE -----------------------------
    //-- stałe
    private final static int BITMAPFILEHEADER_SIZE = 14;
    private final static int BITMAPINFOHEADER_SIZE = 40;
    //-- czy
    //-- zmienne
//--- dane do indentyfikacji
    //private int bfSize = 0; bedzie w nizej

//--- BMP naguwek
    private int bfSize = 0;
    private int bfReserved1 = 0;
    private int bfReserved2 = 0;
    private int bfOffBits = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE;

//--- BMP naguwek, zmienne pliku
    private int biSize = BITMAPINFOHEADER_SIZE;
    private int biWidth = 0;
    private int biHeight = 0;
    private int biPlanes = 1;
    private int biBitCount = 24;
    private int biCompression = 0;
    private int biSizeImage = 0;
    private int biXPelsPerMeter = 0;
    private int biYPelsPerMeter = 0;
    private int biClrUsed = 0;
    private int biClrImportant = 0;
    private int biClrRotation = 0;
    private int biReserved = 0;
    private byte[] biElse;

    private String danePoDanych = "";

//--- ZAWARTOŚĆ PIXELI
    private byte[] pixele;
// ------------------------------- ZIENNE PUBLICZNE
    //-- czy
    //-- zmienne

// ------------------------------- KONSTRUKTORY
    /**
     * Konstruktor pusty.
     *
     */
    public PlikBMP() {
    }

// ******************************** PUBLICZNE **********************************
// ------------------------------- FUNKCJE KRYTYCZNE ---------------------------

    public void init(File file) throws StegException, IOException {


        plik = file;

        InputStream in = new FileInputStream(file);
        DataInputStream dataIn = new DataInputStream(in);

        try{


            // --- nie mozna stworzyc wiekszej tablicy niz integer, wiec trza to czeknac
            readHeader(dataIn);

            // --- zobaczmy czy nie ma czegoś na końcu ukrytego ;)
            if(plik.length()>bfSize) {
                long sizeMax = plik.length()-bfSize;
                if(sizeMax>Integer.MAX_VALUE) {
                    danePoDanych = "bity len["+sizeMax+"]";

                } else{
                    dataIn.skip(bfSize-bfOffBits);
                    byte[] biNdamiar = new byte[ (int)sizeMax ];
                    dataIn.readFully(biNdamiar);
                    danePoDanych = new String(biNdamiar);
                }
            }
        }finally{
            dataIn.close();
        }
    }
    
    /**
     * Funkcja steg z możliwością monitorowania procesu.
     * @return
     */
    @Override
    public Void doInBackground() {
        try {
            stegProcess();

            // -------------------------- INFO -----------------------------
            //wychodzi na to że wg Google Exceptiony wyżucane przez tą funckje doInB..
            // nigdzie nie są łapane, zatem trzeba je przechować i o nich pamiętać, MASAKRA !!
            //Exception przerywa oczywwiście działanie funkcji, a więc stąd idzie do done()
        } catch (StegException ex) {

            stegEx = ex;

        } catch (Exception ex) {

            stegEx = new StegException( ex, StegException.BLAD_UNSUPORTED, "");
            //this.firePropertyChange("state", StateValue.STARTED, StateValue.DONE);
        }
        return null;
    }

    @Override
    public void done() {

        /*W sumie to nic.*/

    }

// ------------------------------- FUNKCJE DODATKOWE ---------------------------

    public long getPojemnosc() {
        throw new UnsupportedOperationException("Not supported yet. ");
        //return bfSize-bfOffBits;
    }

    public void generateRandom(int width, int height) {


        //obliczenie wielkosci pliku, z poprawka na:
                        /*Należy zwrócić uwagę, że (poniekąd ze względów historycznych)
        w wierszu danych pliku BMP jest zawsze zapisana wielokrotność 4 bajtów.
        Jeśli wiersz danych ma długość (w bajtach) inną, niż podzielna przez 4,
        to dopisuje się bajty o wartości 0.
         ***********************/
        int pad = 0;
        pad = (4 - ((width * 3) % 4)) * height;

        if (4 - ((width * 3) % 4) == 4) {
            pad = 0;
        }

        biSizeImage = ((width * height) * 3) + pad;
        bfSize = biSizeImage + BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE;
        biWidth = width;
        biHeight = height;

        //reszta parametrow
        //bfType = new byte[]{(byte) 'B', (byte) 'M'};
        //bfSize = 0;
        bfReserved1 = 0;
        bfReserved2 = 0;
        bfOffBits = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE;

        biSize = BITMAPINFOHEADER_SIZE;
        //biWidth = 0;
        //biHeight = 0;
        biPlanes = 1;
        biBitCount = 24;
        biCompression = 0;
        //biSizeImage = 0;
        biXPelsPerMeter = 0;
        biYPelsPerMeter = 0;
        biClrUsed = 0;
        biClrImportant = 0;
        biClrRotation = 0;
        biReserved = 0;

        pixele = new byte[biSizeImage];
        // tu mog wystepowac bełąd, z nagowek.length !!!?! spr
        Random rnd = new Random();
        for (int i = 0; i < biSizeImage; i++) {
            pixele[i] = (byte) rnd.nextInt(256);
        //pixele[i] = (byte) ((byte) i % 256);
        }

    }

    public MojaLinkedHashMap getMetaDane() {

        MojaLinkedHashMap map = new MojaLinkedHashMap();

        map.put("Nazwa", plik.getName() );
        map.put("bfSize: ", bfSize );
        map.put("bfReserved1: ", bfReserved1 );
        map.put("bfReserved2: ", bfReserved2 );
        map.put("bfOffBits: ", bfOffBits );
        map.put("biSize: ", biSize );
        map.put("biWidth: ", biWidth );
        map.put("biHeight: ", biHeight );
        map.put("biPlanes: ", biPlanes );
        map.put("biBitCount: ", biBitCount );
        map.put("biCompression: ", biCompression );
        map.put("biSizeImage: ", biSizeImage );
        map.put("biXPelsPerMeter: ", biXPelsPerMeter );
        map.put("biYPelsPerMeter: ", biYPelsPerMeter );
        map.put("biClrUsed: ", biClrUsed );
        map.put("biClrImportant: ", biClrImportant );
        map.put("biClrRotation: ", biClrRotation );
        map.put("biReserved: ", biReserved );

        if(bfOffBits>BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE)
            map.put("biElse: ", new String(biElse) );

        if(!danePoDanych.equals(""))
            map.put("Stopka: ", danePoDanych );

        return map;
    }


// ------------------------------- FUNKCJE dziwne ------------------------------
    
    //--przydatnosc tego sie okaze, ale chiba sie zapakuje do ImageBuffer i oleje to!
    public byte[] getPixelArray() {

        //return header;
        return pixele;


    }

    public byte[] getHeaderArray() {

        byte[] head = new byte[bfOffBits];
        //byte[] head = new byte[55];
        byte[] temp = new byte[4];


        head[0] = 'B';
        head[1] = 'M';

        temp = intTo4Bytes(bfSize);
        head[2] = temp[0];
        head[3] = temp[1];
        head[4] = temp[2];
        head[5] = temp[3];

        temp = intTo2Bytes(bfReserved1);
        head[6] = temp[0];
        head[7] = temp[1];

        temp = intTo2Bytes(bfReserved2);
        head[8] = temp[0];
        head[9] = temp[1];

        temp = intTo4Bytes(bfOffBits);
        head[10] = temp[0];
        head[11] = temp[1];
        head[12] = temp[2];
        head[13] = temp[3];

        temp = intTo4Bytes(biSize);
        head[14] = temp[0];
        head[15] = temp[1];
        head[16] = temp[2];
        head[17] = temp[3];

        temp = intTo4Bytes(biWidth);
        head[18] = temp[0];
        head[19] = temp[1];
        head[20] = temp[2];
        head[21] = temp[3];

        temp = intTo4Bytes(biHeight);
        head[22] = temp[0];
        head[23] = temp[1];
        head[24] = temp[2];
        head[25] = temp[3];

        temp = intTo2Bytes(biPlanes);
        head[26] = temp[0];
        head[27] = temp[1];

        temp = intTo2Bytes(biBitCount);
        head[28] = temp[0];
        head[29] = temp[1];

        temp = intTo4Bytes(biCompression);
        head[30] = temp[0];
        head[31] = temp[1];
        head[32] = temp[2];
        head[33] = temp[3];

        temp = intTo4Bytes(biSizeImage);
        head[34] = temp[0];
        head[35] = temp[1];
        head[36] = temp[2];
        head[37] = temp[3];

        temp = intTo4Bytes(biXPelsPerMeter);
        head[38] = temp[0];
        head[39] = temp[1];
        head[40] = temp[2];
        head[41] = temp[3];

        temp = intTo4Bytes(biYPelsPerMeter);
        head[42] = temp[0];
        head[43] = temp[1];
        head[44] = temp[2];
        head[45] = temp[3];

        temp = intTo4Bytes(biClrUsed);
        head[46] = temp[0];
        head[47] = temp[1];
        head[48] = temp[2];
        head[49] = temp[3];

        head[50] = (byte) biClrImportant;
        head[51] = (byte) biClrRotation;

        temp = intTo2Bytes(biReserved);
        head[52] = (byte) 'X';
        head[53] = (byte) 'X';

        if (bfOffBits > 54) {
            for (int i = 0; i < head.length - 54; i++) {
                head[54 + i] = biElse[i];
            }
        }


        return head;


    }

// ------------------------------- FUNKCJE CZY ---------------------------------


// ******************************** PRYWATNE ***********************************
// ------------------------------- FUNKCJE KRYTYCZNE

    @Override
    public void stegProcess() throws StegException {


        DataOutputStream dataOut;
        DataInputStream dataIn; // nie wiem czy poprawnie to bez finally ???

        try {
            //1 przygotowanie Sekret

            //plik z sekretem, może ulec zmianie po gzipie,
            //gzip owany plik wzucimy do sekretu, a potem go zastapimy starym
            File tempSekretFile = sekret.getFile();

            initSekret();

            //tearaz 50% powinno być ustawionr
            // progress start
            addProgressInPercent(1);


            // ================== WŁAŚCIWA STEGANOGRAFIA



            //otwarcie pliku wzorca

            processNag = "Krok  4/9: rozpoczęcie steganografi";
            processMsg += " ..rozpoczęcie steganografi\n ..przygotowanie danych\n";
            addProgressInPercent(1);

            InputStream in = new FileInputStream(plik);
            dataIn = new DataInputStream(in);

            // otwarcie pliku wzorca+info
            OutputStream out = new FileOutputStream(fileOut);
            dataOut = new DataOutputStream(out);

            processNag = "Krok  5/9: otwarcie plików";
            processMsg += " ..otwarcie strumienia: " + plik.getAbsolutePath() + "\n";
            processMsg += " ..otwarcie strumienia: " + fileOut.getAbsolutePath() + "\n";
            addProgressInPercent(1);


            //start, init proces
            sekret.start();

            //3 wczytujemy nagowek
            int licznik = 0;
            while (in.available() != 0 && licznik++ < bfOffBits) {
                dataOut.write(dataIn.read());
            }

            processNag = "Krok  6/9: wczytanie nagłówka";
            processMsg += " ..wczytano nagłówek: bitów [" + licznik + "] \n";
            addProgressInPercent(1);



            //4 wczytaj dane
            byte bSteg, bMsg;
            int bns = sekret.getBitowNaSample();


            processNag = "Krok  7/9: steganowanie";
            processMsg += " ..steganowanie w ["+bfSize+"]bitach \n";
            addProgressInPercent(1);



            double proc = (double)50 / bfSize; //50% ma to zajac


            //zapodam po 8
//System.out.print("\nHEX PMSG:");
            while ( /*in.available() !=0 &&*/licznik++ < bfSize) { //odkomentowane, bo jesli się niemieści to
                //przechwyci ten error EOF exeption !!! PO czym bedzie mozna poznac ze za malo jest miejsca


                bMsg = sekret.getNextMessageBit();

                //czy już
                if (sekret.isEOF()) {
                    break;
                }

                // pobierz byte
                bSteg = dataIn.readByte();

                // czyszczenie bitow i dodanie
                bSteg >>= bns;
                bSteg <<= bns;
                bSteg |= bMsg;

                //wpisz biciki
                dataOut.write(bSteg);

                //
                addProgressInPercent(proc);

            }



            processNag = "Krok  8/9: dopełnianie pliku";
            processMsg += " ..dopełnianie [" + (bfSize - licznik) + "]bitów \n";
            addProgressInPercent(1);


            //5 wczytaj wszystko pozostałe
            while (in.available() != 0) {
                dataOut.write(dataIn.read());
                //prog
                addProgressInPercent(proc);
            }
            dataOut.close();
            dataIn.close();
            
            // jesli byl gzip to sekretme byl ten plik przed gzipowaniem, trzeba go przywrocic
            sekret.setFile(tempSekretFile);


            processNag = "Krok  9/9: zakańczanie";
            processMsg += " ..zamykanie strumieni [OK] \n"+licznik+"]["+bfSize;
            processMsg += " ..zczyszczenie bufora [OK] \n";
            processMsg += " ..GIZP cancel [OK] \n";
            addProgressInPercent(1);



        } catch (EOFException eofe) {
            //jak sie zdarzy
            throw new StegException(eofe, StegException.BLAD_ZLY_FORMAT_PLIKU, "Za mało miejsca aby schować wszystkie dane.");

        } catch (FileNotFoundException ex) {
            throw new StegException(ex, StegException.BLAD_MODYFIKACJI_PLIKU, "");
        } catch (IOException ex) {
            throw new StegException(ex, StegException.BLAD_MODYFIKACJI_PLIKU, "");
        }


    }

    public void unsteg( UnSekret unpaczka ) throws StegException, IOException {


            //2. otworz odczyt/zapis, bo jak belad to po co wpisywac
            OutputStream out = new FileOutputStream( unpaczka.getFile() ); //wczytujemy tam gdzie wskazuje unpaczka
            DataOutputStream undataOut = new DataOutputStream(out);

            InputStream in = new FileInputStream( this.getFile() ); //z tegoż pliku
            DataInputStream undataIn = new DataInputStream(in);

        try {

            //3 przeskocz nagowek
            int licznik = bfOffBits;
            undataIn.skipBytes(bfOffBits);

            //4 wczytaj dane
            byte bSteg,bInfo=0;
            int bns = unpaczka.getSkBitowNaSample();

            // stworz maske
            byte maska = (byte) 0x7F;
            if(bns!=8)
                maska >>= 7-bns;
            else
                maska = (byte) 0xFF;

            int licznikBitow = 8-bns;

            int licznikTaga = 0;
            boolean fHaslo = true;
            int ileSczytano = 0;
            byte[] tagBits = new byte[13];
            SekretInfo sinfo = new SekretInfo();

            while( /*in.available() !=0 &&*/ licznik++<bfSize ) {

                // reset przesumiecia
                if(licznikBitow<0) {

    /***************************************************************************
     * TO DO:
     * Ehh this is bad okey, this is really bad ...
     *
     * rozwiazanie na tenczas na szybko bo mnie sie nie chce
     */
//byc moze tag
if(licznikTaga<13) {

    //zapis bo moze to tag
    tagBits[licznikTaga] = bInfo;



    if(++licznikTaga==13) {
        //wczytano cały tag, ale czy napewno ?
        UnSekret.parseSekretTag(sinfo, tagBits);

// blad, oczekiwano znacznika a nie ma lub znacznik jest wiec spadowa, bo moze byc hasko
        if(unpaczka.isZnacznik()!= sinfo.isTag() )
            throw new StegException(new Exception("steg rozny tag() set"), StegException.BLAD_ZLY_FORMAT_PLIKU,"W pliku przeszukiwanym wartość znacznik jest równa = " + sinfo.isTag() );

        if(unpaczka.isCzyHaslo()!= sinfo.isHaslo() )
            throw new StegException(new Exception("steg: haslo wymagane"), StegException.BLAD_ZLY_FORMAT_PLIKU,"Brak dostępu!" );

        //zapiszmy teraz to, badz nie
        if(!sinfo.isTag() ) undataOut.write( tagBits );

    }

}else{

    // byc moze haslo
    if( fHaslo && licznikTaga>=13 && licznikTaga<53 && sinfo.isHaslo() ) { // 45 to dlugosc haszu

        // ale potem sprawdzimy tu haslo
        
        System.out.println(licznikTaga +":-<>-:"+(char)bInfo);

        if( bInfo!=unpaczka.getSkHaslo()[licznikTaga-13] )
            throw new StegException(new Exception("steg: zle haslo:"+(char)tagBits[licznikTaga-13]+"!="+(char)unpaczka.getSkHaslo()[licznikTaga-13]), StegException.BLAD_ZLY_FORMAT_PLIKU,"Złe hasło!" );
        licznikTaga++;
    }else{

        //czy koniec wiadomosci wg taga ?
        if(sinfo.isTag() && ileSczytano>=sinfo.getLength() )
            break;

        // JUZ NE TAG WIEC ZAPIS DO pliku
        undataOut.writeByte( bInfo );
        ileSczytano++;

    }
    fHaslo = !fHaslo;
}
// ============= THE END TO DO  THE END TO DO  THE END TO DO  THE END TO DO ====



                    licznikBitow = 8-bns;
                    bInfo=0;

                }

                //pobranie bitow
                bSteg = undataIn.readByte();
                bSteg &= maska;

                //przesuniecie pobranych bitow
                bSteg <<= licznikBitow;

                //uzulelnienie informacji
                bInfo |=bSteg;

                licznikBitow-=bns;


                //dataOut.write( bSteg );



            }


        }catch(EOFException eofe) {
            //jak sie zdarzy
            throw new StegException(eofe, StegException.BLAD_ZLY_FORMAT_PLIKU,"Za mało miejsca aby schować wszystkie dane.");

        }finally{
            undataOut.close();
            undataIn.close();
        }

        //teraz nalezalo by wiadomosc odzipowac !!!
        



    }


// ------------------------------- FUNKCJE POMOCNICZE

    private void readHeader(DataInputStream dataIn)  throws StegException, IOException {

        try {


        short nagowek = dataIn.readShort();
        if (nagowek != 0x424d)
            throw new StegException( new Exception("steg err"),StegException.BLAD_ZLY_FORMAT_PLIKU,"Nagłówek BMP nie został znaleziony!");

        bfSize = Integer.reverseBytes( dataIn.readInt() );
        bfReserved1 = Short.reverseBytes( dataIn.readShort() );
        bfReserved2 = Short.reverseBytes( dataIn.readShort() );
        bfOffBits = Integer.reverseBytes( dataIn.readInt() );
        biSize = Integer.reverseBytes( dataIn.readInt() );
        biWidth = Integer.reverseBytes( dataIn.readInt() );
        biHeight = Integer.reverseBytes( dataIn.readInt() );
        biPlanes = Short.reverseBytes( dataIn.readShort() );
        biBitCount = Short.reverseBytes( dataIn.readShort() );
        biCompression = Integer.reverseBytes( dataIn.readInt() );
        biSizeImage = Integer.reverseBytes( dataIn.readInt() );
        biXPelsPerMeter = Integer.reverseBytes( dataIn.readInt() );
        biYPelsPerMeter = Integer.reverseBytes( dataIn.readInt() );
        biClrUsed = Integer.reverseBytes( dataIn.readInt() );
        biClrImportant = dataIn.readByte();
        biClrRotation = dataIn.readByte();
        biReserved = Short.reverseBytes( dataIn.readShort() );

        //czy jest jakiś nagówek
        if(bfOffBits>54) {
            biElse = new byte[bfOffBits-(BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE)];
            dataIn.readFully(biElse);

        }


       }catch(EOFException eofex ){
        //przecie znaczmik BM nie oznacza że to zaraz jest BMP !!! lub że coś nie jest źle ;)
           throw new StegException( new Exception("steg err"),StegException.BLAD_ZLY_FORMAT_PLIKU,"Nagłówek BMP nie został znaleziony!");

       }


    //biElse


    }


    private static byte[] intTo4Bytes(int temp) {

        byte ret[] = new byte[4];
        ret[0] = (byte) (temp & 0x00FF);
        ret[1] = (byte) ((temp >> 8) & 0x000000FF);
        ret[2] = (byte) ((temp >> 16) & 0x000000FF);
        ret[3] = (byte) ((temp >> 24) & 0x000000FF);

        return ret;

    }

    private static byte[] intTo2Bytes(int temp) {

        byte ret[] = new byte[2];

        ret[0] = (byte) (temp & 0x00FF);
        ret[1] = (byte) ((temp >> 8) & 0x00FF);

        return ret;
    }

    //dziala w invert, od konca do poczatku i nich tak zostanie
    private static int byteArrayToInt(byte[] b, int offset) {
        int value = 0;
        for (int i = 0; i < 4; i++) {
            int shift = (4 - 1 - i) * 8;
            value += (b[i + offset] & 0x000000FF) << shift;
        }
        return value;
    }

    //toString array
    private static String toStringArry(byte[] b, int przerwa) {
        String text = "";
        for (int i = 0; i < b.length; i++) {
            text += " [" + Integer.toHexString(b[i]) + "]";
            if ((i + 1) % przerwa == 0) {
                text += "\n";
            }


        }
        return text;
    }



    // GET SET
    public int getBfOffBits() {
        return bfOffBits;
    }

    public void setBfOffBits(int bfOffBits) {
        this.bfOffBits = bfOffBits;
    }

    public int getBfReserved1() {
        return bfReserved1;
    }

    public void setBfReserved1(int bfReserved1) {
        this.bfReserved1 = bfReserved1;
    }

    public int getBfSize() {
        return bfSize;
    }

    public void setBfSize(int bfSize) {
        this.bfSize = bfSize;
    }

    public int getBiBitCount() {
        return biBitCount;
    }

    public void setBiBitCount(int biBitCount) {
        this.biBitCount = biBitCount;
    }

    public int getBiClrImportant() {
        return biClrImportant;
    }

    public void setBiClrImportant(int biClrImportant) {
        this.biClrImportant = biClrImportant;
    }

    public int getBiClrRotation() {
        return biClrRotation;
    }

    public void setBiClrRotation(int biClrRotation) {
        this.biClrRotation = biClrRotation;
    }

    public int getBiClrUsed() {
        return biClrUsed;
    }

    public void setBiClrUsed(int biClrUsed) {
        this.biClrUsed = biClrUsed;
    }

    public int getBiCompression() {
        return biCompression;
    }

    public void setBiCompression(int biCompression) {
        this.biCompression = biCompression;
    }

    public byte[] getBiElse() {
        return biElse;
    }

    public void setBiElse(byte[] biElse) {
        this.biElse = biElse;
    }

    public int getBiHeight() {
        return biHeight;
    }

    public void setBiHeight(int biHeight) {
        this.biHeight = biHeight;
    }

    public int getBiPlanes() {
        return biPlanes;
    }

    public void setBiPlanes(int biPlanes) {
        this.biPlanes = biPlanes;
    }

    public int getBiReserved() {
        return biReserved;
    }

    public void setBiReserved(int biReserved) {
        this.biReserved = biReserved;
    }

    public int getBiSize() {
        return biSize;
    }

    public void setBiSize(int biSize) {
        this.biSize = biSize;
    }

    public int getBiSizeImage() {
        return biSizeImage;
    }

    public void setBiSizeImage(int biSizeImage) {
        this.biSizeImage = biSizeImage;
    }

    public int getBiWidth() {
        return biWidth;
    }

    public void setBiWidth(int biWidth) {
        this.biWidth = biWidth;
    }

    public int getBiXPelsPerMeter() {
        return biXPelsPerMeter;
    }

    public void setBiXPelsPerMeter(int biXPelsPerMeter) {
        this.biXPelsPerMeter = biXPelsPerMeter;
    }

    public int getBiYPelsPerMeter() {
        return biYPelsPerMeter;
    }

    public void setBiYPelsPerMeter(int biYPelsPerMeter) {
        this.biYPelsPerMeter = biYPelsPerMeter;
    }

    public String getDanePoDanych() {
        return danePoDanych;
    }

    public void setDanePoDanych(String danePoDanych) {
        this.danePoDanych = danePoDanych;
    }




    @Deprecated
    public void unsteg(File fileIn, UnSekret unpaczka ) throws StegException, IOException {

    }





}
